package com.vesystem.vegua.config;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.vesystem.vegua.modules.common.dto.SysAuthorizationDto;
import com.vesystem.vegua.modules.common.entity.SysAuthorization;
import com.vesystem.vegua.modules.common.mapper.RemoteMonitoringMapper;
import com.vesystem.vegua.modules.common.mapper.SysAuthorizationMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @auther hcy
 * @create 2020-12-11 9:56
 * @Description
 */
@Component
public class ServerListener implements ApplicationListener<ContextRefreshedEvent> {
    @Autowired
    private SysAuthorizationMapper sysAuthorizationMapper;
    @Autowired
    private RemoteMonitoringMapper remoteMonitoringMapper;

    private static Logger log = LoggerFactory.getLogger(ServerListener.class);
    /**
     * 注册信息
     */
    public static final SysAuthorizationDto SIGN = new SysAuthorizationDto();

    /**
     * 系统内置的账户数量，该账户不占用系统授权数
     * 默认只有 root 一个账户是系统内置的
     */
    public static final int SYSTEM_ACCOUNT_NUM = 1;
    /**
     * token的本地缓存
     */
    public static Map<String,String> TOKEN_CACHE = new ConcurrentHashMap<>();
    /**
     *  缓存需要对操作行为经行监控的服务器列表
     */
    public static Set<Integer> REMOTE_MOITORING = new CopyOnWriteArraySet<>();

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        try {
            initBaseFolder();
            loadLoginInfo();
            loadRemoteMoitoringSet();
        } catch (IOException e) {
            log.error("系统启动时异常！注册信息为："+SIGN.toString());
            log.error(e.getLocalizedMessage(),e);
        }
    }

    /**
     * 初始化基础文件夹
     */
    public void initBaseFolder(){
        File basePath = new File(GlobalConfig.BASE_PATH);
        if ( !basePath.exists() ){
            basePath.mkdirs();
        }
        File baseIcon = new File(GlobalConfig.BASE_PATH+GlobalConfig.BASE_PATH_ABOUT_ICON);
        if ( !baseIcon.exists() ){
            baseIcon.mkdirs();
        }

        //因为jar中无法正常复制文件，取消这段关于appIcon的逻辑
//        String dist =  Thread.currentThread().getContextClassLoader().getResource("").getPath()+ "config/appIcon/";
//        FileUtil.copy(dist,GlobalConfig.BASE_PATH,false);
        File baseOther = new File(GlobalConfig.BASE_PATH + GlobalConfig.BASE_PATH_ABOUT_OTHER);
        if ( !baseOther.exists() ){
            baseOther.mkdirs();
        }
    }

    /**
     * 加载远端服务器监控列表到缓存中
     */
    public void loadRemoteMoitoringSet(){
        List<Integer> list = remoteMonitoringMapper.selectAllMonitoringList();
        REMOTE_MOITORING.addAll(list);
    }
    /**
     * 加载注册信息
     * @throws IOException
     */
    public void loadLoginInfo() throws IOException{
        File file = new File(GlobalConfig.BASE_PATH+"secure.hcy");
        if ( !file.exists() ){
           file.createNewFile();
            byte[] key = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
            FileOutputStream fos = new FileOutputStream(file);
            fos.write( key );
            fos.close();
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH,1);
            JSONObject j = new JSONObject();
            j.set("org","试用");
            j.set("maxUser",100);
            j.set("expiration",calendar.getTime());
            AES aes = SecureUtil.aes(key);
            String encryptHex = aes.encryptHex(j.toStringPretty());
            sysAuthorizationMapper.insert(new SysAuthorization(null,encryptHex));
            SIGN.setOrg("试用");
            SIGN.setMaxUser(100);
            SIGN.setExpiration(calendar.getTime().getTime());
        }else {
            SysAuthorization sysAuto = sysAuthorizationMapper.selectById(1);
            byte[] bytes = new byte[16];
            FileInputStream fis = new FileInputStream(file);
            fis.read(bytes);
            fis.close();
            AES aes = SecureUtil.aes(bytes);
            byte[] decrypt = aes.decrypt(HexUtil.decodeHex(sysAuto.getAuthorization()));
            String jsonStr = new String(decrypt,"UTF-8");
            JSONObject signObj = JSONUtil.parseObj(jsonStr);
            SIGN.setOrg(signObj.getStr("org"));
            SIGN.setMaxUser(signObj.getInt("maxUser"));
            SIGN.setExpiration(signObj.getLong("expiration"));
        }
    }

}
